import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JPanel;


public class GameView extends JPanel {
	private static final long serialVersionUID = 1L;
	private static double current_time = 0;
	private static double last_time = 0;
	private Player player;
	private Map map;
	private int fps;

	private Font horrorFont;
	private Image backGroundImage;

	private int     printX;
	private int     printY;
	private boolean hasScorePrinted;
	private double  beginTimeScorePrint;
	private String  scorePointsString;
	
	private int start_pos_y = 150;
	private int background_pos_y = 0;

	public GameView(Player player, Map map) {
		this.player = player;
		this.map = map;
		this.loadRessource();
	}

	/**
	 * Charge les ressources multimedias necessaires.
	 */
	public void loadRessource() {
		try {
			this.backGroundImage = ImageIO.read((getClass().getResource("Ressources/bg-clouds.png")));
			java.io.InputStream is = this.getClass().getResourceAsStream("font/horror.ttf");
			this.horrorFont = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(Font.BOLD, 20f);
		} 
		catch (IOException e) {e.printStackTrace();} 
		catch (FontFormatException e) {e.printStackTrace();}
	}

	public void setPrintScore(int x, int y, int score, int combo_) {
		this.printX = x;
		this.printY = y;
		this.hasScorePrinted = true;
		this.scorePointsString = "";
		if(combo_ >= 2)
			this.scorePointsString = "Combo : ";
		this.scorePointsString += score < 0 ?  "-"+score*combo_ : "+"+score*combo_;
		this.beginTimeScorePrint = System.currentTimeMillis();
	}

	/**
	 * Permet l'affichage generale du jeu.
	 */
	public void paintComponent(Graphics g) {
		this.drawBackground(g);
		this.drawMap(g);
		this.drawPlayer(g);
		this.drawTargets(g);
		this.drawGUI(g);
		if(start_pos_y > 0){
			start_pos_y -= 3;
			background_pos_y -= 3;
		}
	}

	private void drawBackground(Graphics g) {
		g.setColor(new Color(0x8e, 0xc1, 0xda));
		g.fillRect(0, 0, Windows.WIDTH, Windows.HEIGHT);
		g.drawImage(this.backGroundImage, (int) Windows.position_bg, background_pos_y, 2247, 190, null);

		Windows.position_bg -= 0.5;
		if(Windows.position_bg < -1210)
			Windows.position_bg = -646;
	}

	private void drawMap(Graphics g) {
		for(int i=0; i< GameControler.NUMBER_OF_TILES_HEIGHT; ++i) {
			for(int y=0; y< GameControler.NUMBER_OF_TILES_WIDTH; ++y) {
				g.drawImage(map.getImage(y, i),y*GameControler.TILES_SIZE, i*GameControler.TILES_SIZE+start_pos_y, GameControler.TILES_SIZE, GameControler.TILES_SIZE, null);
			}	
		}
	}

	private void drawPlayer(Graphics g) {
		if(this.player.getBird() != null) {
			g.setColor(Color.BLACK);
			int timeLeft = (int) player.getBird().getTimeleft();
			if(timeLeft < 5) g.setColor(Color.red);
			if(timeLeft >= 0)
				g.drawString(String.valueOf(timeLeft),(int) player.getX(), (int) player.getY()-10);
			g.setColor(Color.black);
			g.drawImage(player.getBird().getImage(),(int) player.getX(),(int) player.getY(), player.getBird().imageWidth, player.getBird().imageHeight, null);
		}

		if(this.player.hasEgg())
			g.drawImage(player.getEgg().getImage(),(int) player.getEgg().x, (int) player.getEgg().y, GameControler.TILES_SIZE, GameControler.TILES_SIZE, null);			
	}

	private void drawTargets(Graphics g) {
		ArrayList<Target> array = TargetControler.getArray();
		for(Target element : array){
		
				g.drawImage(element.getImage(),(int)element.getX(),(int)element.getY()+start_pos_y,element.getImageWidth(),element.getImageHeight(), null);
		}
	}

	private void drawGUI(Graphics g) {
		this.drawUIScore(g);
		this.drawUIBirdsLeft(g);
		this.drawUIfps(g);
		this.drawHitScore(g);
	}

	private void drawUIScore(Graphics g){
		g.drawString("Score : "+player.getScore(), Windows.WIDTH-75, 30);
	}

	private void drawUIBirdsLeft(Graphics g){
		Image[] BirdsImage = this.player.getBirdsImages();
		int 	posX = (this.player.getX() <= 100) ? (int) (100 - this.player.getX()) : 0;

		if(BirdsImage.length > 1) {
			g.drawRect(5-posX, 2, 75, BirdsImage.length*25);
			g.drawString("Next birds", 10-posX, 15);
			for(int i=0; i<BirdsImage.length-1; ++i) {
				g.drawImage(BirdsImage[i],15-posX,25+i*(25),20,20, null);
				g.drawString(String.valueOf(player.getBirdTimeLeftWhenPaused(i)),45-posX,40+i*(25));	
			}
		}
		else
			g.drawString("No more bird !", 10, 15);
	}

	private void drawUIfps(Graphics g){
		g.drawString("FPS : "+fps, Windows.WIDTH-55, 15);
		last_time = current_time;
		current_time = System.currentTimeMillis();
		fps =(int) ((int) 1000*(1.0 / (current_time - last_time)));
	}

	private void drawHitScore(Graphics g) {
		if( this.hasScorePrinted && 
				(this.beginTimeScorePrint + 1000) > System.currentTimeMillis())
		{
			g.setFont(horrorFont);
			g.drawString(this.scorePointsString,(int) this.printX-20,(int) this.printY-40);
			printY--;
		}
		else if(this.hasScorePrinted){
			this.hasScorePrinted = false;
			this.beginTimeScorePrint = 0;
			this.scorePointsString = "";
		}
	}
}
